1 //搜网上的javabrowser都不支持中文在线修改保存,且文件名包含中文。修改如下 2 3 <%@page import="java.util.*, 4 java.net.*, 5 java.text.*, 6 java.util.zip.*, 7 java.io.*" 8 contentType="text/html; charset=utf-8" pageEncoding="utf-8" 9 %> 10 <%! 11 //FEATURES 12 private static final boolean NATIVE_COMMANDS = true; 13 /** 14 *If true, all operations (besides upload and native commands) 15 *which change something on the file system are permitted 16 */ 17 private static final boolean READ_ONLY = false; 18 //If true, uploads are allowed even if READ_ONLY = true 19 private static final boolean ALLOW_UPLOAD = true; 20 21 //Allow browsing and file manipulation only in certain directories 22 private static final boolean RESTRICT_BROWSING = false; 23 //If true, the user is allowed to browse only in RESTRICT_PATH, 24 //if false, the user is allowed to browse all directories besides RESTRICT_PATH 25 private static final boolean RESTRICT_WHITELIST = false; 26 //Paths, sperated by semicolon 27 //private static final String RESTRICT_PATH = "C:\\CODE;E:\\"; //Win32: Case important!! 28 private static final String RESTRICT_PATH = "/etc;/var"; 29 30 //The refresh time in seconds of the upload monitor window 31 private static final int UPLOAD_MONITOR_REFRESH = 2; 32 //The number of colums for the edit field 33 private static final int EDITFIELD_COLS = 85; 34 //The number of rows for the edit field 35 private static final int EDITFIELD_ROWS = 30; 36 //Open a new window to view a file 37 private static final boolean USE_POPUP = true; 38 /** 39 * If USE_DIR_PREVIEW = true, then for every directory a tooltip will be 40 * created (hold the mouse over the link) with the first DIR_PREVIEW_NUMBER entries. 41 * This can yield to performance issues. Turn it off, if the directory loads to slow. 42 */ 43 private static final boolean USE_DIR_PREVIEW = false; 44 private static final int DIR_PREVIEW_NUMBER = 10; 45 /** 46 * The name of an optional CSS Stylesheet file 47 */ 48 private static final String CSS_NAME = "Browser.css"; 49 /** 50 * The compression level for zip file creation (0-9) 51 * 0 = No compression 52 * 1 = Standard compression (Very fast) 53 * ... 54 * 9 = Best compression (Very slow) 55 */ 56 private static final int COMPRESSION_LEVEL = 1; 57 /** 58 * The FORBIDDEN_DRIVES are not displayed on the list. This can be usefull, if the 59 * server runs on a windows platform, to avoid a message box, if you try to access 60 * an empty removable drive (See KNOWN BUGS in Readme.txt). 61 */ 62 private static final String[] FORBIDDEN_DRIVES = {"a:\\"}; 63 64 /** 65 * Command of the shell interpreter and the parameter to run a programm 66 */ 67 private static final String[] COMMAND_INTERPRETER = {"cmd", "/C"}; // Dos,Windows 68 //private static final String[] COMMAND_INTERPRETER = {"/bin/sh","-c"}; // Unix 69 70 /** 71 * Max time in ms a process is allowed to run, before it will be terminated 72 */ 73 private static final long MAX_PROCESS_RUNNING_TIME = 30 * 1000; //30 seconds 74 75 //Button names 76 private static final String SAVE_AS_ZIP = "Download selected files as (z)ip"; 77 private static final String RENAME_FILE = "(R)ename File"; 78 private static final String DELETE_FILES = "(Del)ete selected files"; 79 private static final String CREATE_DIR = "Create (D)ir"; 80 private static final String CREATE_FILE = "(C)reate File"; 81 private static final String MOVE_FILES = "(M)ove Files"; 82 private static final String COPY_FILES = "Cop(y) Files"; 83 private static final String LAUNCH_COMMAND = "(L)aunch external program"; 84 private static final String UPLOAD_FILES = "Upload"; 85 86 //Normally you should not change anything after this line 87 //---------------------------------------------------------------------------------- 88 //Change this to locate the tempfile directory for upload (not longer needed) 89 private static String tempdir = "."; 90 private static String VERSION_NR = "1.2"; 91 private static DateFormat dateFormat = DateFormat.getDateTimeInstance(); 92 93 public class UplInfo { 94 95 public long totalSize; 96 public long currSize; 97 public long starttime; 98 public boolean aborted; 99 100 public UplInfo() { 101 totalSize = 0l; 102 currSize = 0l; 103 starttime = System.currentTimeMillis(); 104 aborted = false; 105 } 106 107 public UplInfo(int size) { 108 totalSize = size; 109 currSize = 0; 110 starttime = System.currentTimeMillis(); 111 aborted = false; 112 } 113 114 public String getUprate() { 115 long time = System.currentTimeMillis() - starttime; 116 if (time != 0) { 117 long uprate = currSize * 1000 / time; 118 return convertFileSize(uprate) + "/s"; 119 } 120 else return "n/a"; 121 } 122 123 public int getPercent() { 124 if (totalSize == 0) return 0; 125 else return (int) (currSize * 100 / totalSize); 126 } 127 128 public String getTimeElapsed() { 129 long time = (System.currentTimeMillis() - starttime) / 1000l; 130 if (time - 60l >= 0){ 131 if (time % 60 >=10) return time / 60 + ":" + (time % 60) + "m"; 132 else return time / 60 + ":0" + (time % 60) + "m"; 133 } 134 else return time<10 ? "0" + time + "s": time + "s"; 135 } 136 137 public String getTimeEstimated() { 138 if (currSize == 0) return "n/a"; 139 long time = System.currentTimeMillis() - starttime; 140 time = totalSize * time / currSize; 141 time /= 1000l; 142 if (time - 60l >= 0){ 143 if (time % 60 >=10) return time / 60 + ":" + (time % 60) + "m"; 144 else return time / 60 + ":0" + (time % 60) + "m"; 145 } 146 else return time<10 ? "0" + time + "s": time + "s"; 147 } 148 149 } 150 151 public class FileInfo { 152 153 public String name = null, clientFileName = null, fileContentType = null; 154 private byte[] fileContents = null; 155 public File file = null; 156 public StringBuffer sb = new StringBuffer(100); 157 158 public void setFileContents(byte[] aByteArray) { 159 fileContents = new byte[aByteArray.length]; 160 System.arraycopy(aByteArray, 0, fileContents, 0, aByteArray.length); 161 } 162 } 163 164 public static class UploadMonitor { 165 166 static Hashtable uploadTable = new Hashtable(); 167 168 static void set(String fName, UplInfo info) { 169 uploadTable.put(fName, info); 170 } 171 172 static void remove(String fName) { 173 uploadTable.remove(fName); 174 } 175 176 static UplInfo getInfo(String fName) { 177 UplInfo info = (UplInfo) uploadTable.get(fName); 178 return info; 179 } 180 } 181 182 // A Class with methods used to process a ServletInputStream 183 public class HttpMultiPartParser { 184 185 //private final String lineSeparator = System.getProperty("line.separator", "\n"); 186 private final int ONE_MB = 1024 * 1; 187 188 public Hashtable processData(ServletInputStream is, String boundary, String saveInDir, 189 int clength) throws IllegalArgumentException, IOException { 190 if (is == null) throw new IllegalArgumentException("InputStream"); 191 if (boundary == null || boundary.trim().length() < 1) throw new IllegalArgumentException( 192 "\"" + boundary + "\" is an illegal boundary indicator"); 193 boundary = "--" + boundary; 194 StringTokenizer stLine = null, stFields = null; 195 FileInfo fileInfo = null; 196 Hashtable dataTable = new Hashtable(5); 197 String line = null, field = null, paramName = null; 198 boolean saveFiles = (saveInDir != null && saveInDir.trim().length() > 0); 199 boolean isFile = false; 200 if (saveFiles) { // Create the required directory (including parent dirs) 201 File f = new File(saveInDir); 202 f.mkdirs(); 203 } 204 line = getLine(is); 205 if (line == null || !line.startsWith(boundary)) throw new IOException( 206 "Boundary not found; boundary = " + boundary + ", line = " + line); 207 while (line != null) { 208 if (line == null || !line.startsWith(boundary)) return dataTable; 209 line = getLine(is); 210 if (line == null) return dataTable; 211 stLine = new StringTokenizer(line, ";\r\n"); 212 if (stLine.countTokens() < 2) throw new IllegalArgumentException( 213 "Bad data in second line"); 214 line = stLine.nextToken().toLowerCase(); 215 if (line.indexOf("form-data") < 0) throw new IllegalArgumentException( 216 "Bad data in second line"); 217 stFields = new StringTokenizer(stLine.nextToken(), "=\""); 218 if (stFields.countTokens() < 2) throw new IllegalArgumentException( 219 "Bad data in second line"); 220 fileInfo = new FileInfo(); 221 stFields.nextToken(); 222 paramName = stFields.nextToken(); 223 isFile = false; 224 if (stLine.hasMoreTokens()) { 225 field = stLine.nextToken(); 226 stFields = new StringTokenizer(field, "=\""); 227 if (stFields.countTokens() > 1) { 228 if (stFields.nextToken().trim().equalsIgnoreCase("filename")) { 229 fileInfo.name = paramName; 230 String value = stFields.nextToken(); 231 if (value != null && value.trim().length() > 0) { 232 fileInfo.clientFileName = value; 233 isFile = true; 234 } 235 else { 236 line = getLine(is); // Skip "Content-Type:" line 237 line = getLine(is); // Skip blank line 238 line = getLine(is); // Skip blank line 239 line = getLine(is); // Position to boundary line 240 continue; 241 } 242 } 243 } 244 else if (field.toLowerCase().indexOf("filename") >= 0) { 245 line = getLine(is); // Skip "Content-Type:" line 246 line = getLine(is); // Skip blank line 247 line = getLine(is); // Skip blank line 248 line = getLine(is); // Position to boundary line 249 continue; 250 } 251 } 252 boolean skipBlankLine = true; 253 if (isFile) { 254 line = getLine(is); 255 if (line == null) return dataTable; 256 if (line.trim().length() < 1) skipBlankLine = false; 257 else { 258 stLine = new StringTokenizer(line, ": "); 259 if (stLine.countTokens() < 2) throw new IllegalArgumentException( 260 "Bad data in third line"); 261 stLine.nextToken(); // Content-Type 262 fileInfo.fileContentType = stLine.nextToken(); 263 } 264 } 265 if (skipBlankLine) { 266 line = getLine(is); 267 if (line == null) return dataTable; 268 } 269 if (!isFile) { 270 line = getLine(is); 271 if (line == null) return dataTable; 272 dataTable.put(paramName, line); 273 // If parameter is dir, change saveInDir to dir 274 if (paramName.equals("dir")) saveInDir = line; 275 line = getLine(is); 276 continue; 277 } 278 try { 279 UplInfo uplInfo = new UplInfo(clength); 280 UploadMonitor.set(fileInfo.clientFileName, uplInfo); 281 OutputStream os = null; 282 String path = null; 283 if (saveFiles) os = new FileOutputStream(path = getFileName(saveInDir, 284 fileInfo.clientFileName)); 285 else os = new ByteArrayOutputStream(ONE_MB); 286 boolean readingContent = true; 287 byte previousLine[] = new byte[2 * ONE_MB]; 288 byte temp[] = null; 289 byte currentLine[] = new byte[2 * ONE_MB]; 290 int read, read3; 291 if ((read = is.readLine(previousLine, 0, previousLine.length)) == -1) { 292 line = null; 293 break; 294 } 295 while (readingContent) { 296 if ((read3 = is.readLine(currentLine, 0, currentLine.length)) == -1) { 297 line = null; 298 uplInfo.aborted = true; 299 break; 300 } 301 if (compareBoundary(boundary, currentLine)) { 302 os.write(previousLine, 0, read - 2); 303 line = new String(currentLine, 0, read3); 304 break; 305 } 306 else { 307 os.write(previousLine, 0, read); 308 uplInfo.currSize += read; 309 temp = currentLine; 310 currentLine = previousLine; 311 previousLine = temp; 312 read = read3; 313 }//end else 314 }//end while 315 os.flush(); 316 os.close(); 317 if (!saveFiles) { 318 ByteArrayOutputStream baos = (ByteArrayOutputStream) os; 319 fileInfo.setFileContents(baos.toByteArray()); 320 } 321 else fileInfo.file = new File(path); 322 dataTable.put(paramName, fileInfo); 323 uplInfo.currSize = uplInfo.totalSize; 324 }//end try 325 catch (IOException e) { 326 throw e; 327 } 328 } 329 return dataTable; 330 } 331 332 /** 333 * Compares boundary string to byte array 334 */ 335 private boolean compareBoundary(String boundary, byte ba[]) { 336 if (boundary == null || ba == null) return false; 337 for (int i = 0; i < boundary.length(); i++) 338 if ((byte) boundary.charAt(i) != ba[i]) return false; 339 return true; 340 } 341 342 /** Convenience method to read HTTP header lines */ 343 private synchronized String getLine(ServletInputStream sis) throws IOException { 344 byte b[] = new byte[1024]; 345 int read = sis.readLine(b, 0, b.length), index; 346 String line = null; 347 if (read != -1) { 348 // line = new String(b, 0, read); 349 //TODO 用给定的编码方式把给定的byte数组转换为字符串 !!!关键之所在!!! 350 line = new String(b, 0, read , "utf-8"); 351 if ((index = line.indexOf('\n')) >= 0) line = line.substring(0, index - 1); 352 } 353 return line; 354 } 355 356 public String getFileName(String dir, String fileName) throws IllegalArgumentException { 357 String path = null; 358 if (dir == null || fileName == null) throw new IllegalArgumentException( 359 "dir or fileName is null"); 360 int index = fileName.lastIndexOf('/'); 361 String name = null; 362 if (index >= 0) name = fileName.substring(index + 1); 363 else name = fileName; 364 index = name.lastIndexOf('\\'); 365 if (index >= 0) fileName = name.substring(index + 1); 366 path = dir + File.separator + fileName; 367 if (File.separatorChar == '/') return path.replace('\\', File.separatorChar); 368 else return path.replace('/', File.separatorChar); 369 } 370 } //End of class HttpMultiPartParser 371 372 /** 373 * This class is a comparator to sort the filenames and dirs 374 */ 375 class FileComp implements Comparator { 376 377 int mode; 378 int sign; 379 380 FileComp() { 381 this.mode = 1; 382 this.sign = 1; 383 } 384 385 /** 386 * @param mode sort by 1=Filename, 2=Size, 3=Date, 4=Type 387 * The default sorting method is by Name 388 * Negative mode means descending sort 389 */ 390 FileComp(int mode) { 391 if (mode < 0) { 392 this.mode = -mode; 393 sign = -1; 394 } 395 else { 396 this.mode = mode; 397 this.sign = 1; 398 } 399 } 400 401 public int compare(Object o1, Object o2) { 402 File f1 = (File) o1; 403 File f2 = (File) o2; 404 if (f1.isDirectory()) { 405 if (f2.isDirectory()) { 406 switch (mode) { 407 //Filename or Type 408 case 1: 409 case 4: 410 return sign 411 * f1.getAbsolutePath().toUpperCase().compareTo( 412 f2.getAbsolutePath().toUpperCase()); 413 //Filesize 414 case 2: 415 return sign * (new Long(f1.length()).compareTo(new Long(f2.length()))); 416 //Date 417 case 3: 418 return sign 419 * (new Long(f1.lastModified()) 420 .compareTo(new Long(f2.lastModified()))); 421 default: 422 return 1; 423 } 424 } 425 else return -1; 426 } 427 else if (f2.isDirectory()) return 1; 428 else { 429 switch (mode) { 430 case 1: 431 return sign 432 * f1.getAbsolutePath().toUpperCase().compareTo( 433 f2.getAbsolutePath().toUpperCase()); 434 case 2: 435 return sign * (new Long(f1.length()).compareTo(new Long(f2.length()))); 436 case 3: 437 return sign 438 * (new Long(f1.lastModified()).compareTo(new Long(f2.lastModified()))); 439 case 4: { // Sort by extension 440 int tempIndexf1 = f1.getAbsolutePath().lastIndexOf('.'); 441 int tempIndexf2 = f2.getAbsolutePath().lastIndexOf('.'); 442 if ((tempIndexf1 == -1) && (tempIndexf2 == -1)) { // Neither have an extension 443 return sign 444 * f1.getAbsolutePath().toUpperCase().compareTo( 445 f2.getAbsolutePath().toUpperCase()); 446 } 447 // f1 has no extension 448 else if (tempIndexf1 == -1) return -sign; 449 // f2 has no extension 450 else if (tempIndexf2 == -1) return sign; 451 // Both have an extension 452 else { 453 String tempEndf1 = f1.getAbsolutePath().toUpperCase() 454 .substring(tempIndexf1); 455 String tempEndf2 = f2.getAbsolutePath().toUpperCase() 456 .substring(tempIndexf2); 457 return sign * tempEndf1.compareTo(tempEndf2); 458 } 459 } 460 default: 461 return 1; 462 } 463 } 464 } 465 } 466 467 /** 468 * Wrapperclass to wrap an OutputStream around a Writer 469 */ 470 class Writer2Stream extends OutputStream { 471 472 Writer out; 473 474 Writer2Stream(Writer w) { 475 super(); 476 out = w; 477 } 478 479 public void write(int i) throws IOException { 480 out.write(i); 481 } 482 483 public void write(byte[] b) throws IOException { 484 for (int i = 0; i < b.length; i++) { 485 int n = b[i]; 486 //Convert byte to ubyte 487 n = ((n >>> 4) & 0xF) * 16 + (n & 0xF); 488 out.write(n); 489 } 490 } 491 492 public void write(byte[] b, int off, int len) throws IOException { 493 for (int i = off; i < off + len; i++) { 494 int n = b[i]; 495 n = ((n >>> 4) & 0xF) * 16 + (n & 0xF); 496 out.write(n); 497 } 498 } 499 } //End of class Writer2Stream 500 501 static Vector expandFileList(String[] files, boolean inclDirs) { 502 Vector v = new Vector(); 503 if (files == null) return v; 504 for (int i = 0; i < files.length; i++) 505 v.add(new File(URLDecoder.decode(files[i]))); 506 for (int i = 0; i < v.size(); i++) { 507 File f = (File) v.get(i); 508 if (f.isDirectory()) { 509 File[] fs = f.listFiles(); 510 for (int n = 0; n < fs.length; n++) 511 v.add(fs[n]); 512 if (!inclDirs) { 513 v.remove(i); 514 i--; 515 } 516 } 517 } 518 return v; 519 } 520 521 /** 522 * Method to build an absolute path 523 * @param dir the root dir 524 * @param name the name of the new directory 525 * @return if name is an absolute directory, returns name, else returns dir+name 526 */ 527 static String getDir(String dir, String name) { 528 if (!dir.endsWith(File.separator)) dir = dir + File.separator; 529 File mv = new File(name); 530 String new_dir = null; 531 if (!mv.isAbsolute()) { 532 new_dir = dir + name; 533 } 534 else new_dir = name; 535 return new_dir; 536 } 537 538 /** 539 * This Method converts a byte size in a kbytes or Mbytes size, depending on the size 540 * @param size The size in bytes 541 * @return String with size and unit 542 */ 543 static String convertFileSize(long size) { 544 int divisor = 1; 545 String unit = "bytes"; 546 if (size >= 1024 * 1024) { 547 divisor = 1024 * 1024; 548 unit = "MB"; 549 } 550 else if (size >= 1024) { 551 divisor = 1024; 552 unit = "KB"; 553 } 554 if (divisor == 1) return size / divisor + " " + unit; 555 String aftercomma = "" + 100 * (size % divisor) / divisor; 556 if (aftercomma.length() == 1) aftercomma = "0" + aftercomma; 557 return size / divisor + "." + aftercomma + " " + unit; 558 } 559 560 /** 561 * Copies all data from in to out 562 * @param in the input stream 563 * @param out the output stream 564 * @param buffer copy buffer 565 */ 566 static void copyStreams(InputStream in, OutputStream out, byte[] buffer) throws IOException { 567 copyStreamsWithoutClose(in, out, buffer); 568 in.close(); 569 out.close(); 570 } 571 572 /** 573 * Copies all data from in to out 574 * @param in the input stream 575 * @param out the output stream 576 * @param buffer copy buffer 577 */ 578 static void copyStreamsWithoutClose(InputStream in, OutputStream out, byte[] buffer) 579 throws IOException { 580 int b; 581 while ((b = in.read(buffer)) != -1) 582 out.write(buffer, 0, b); 583 } 584 585 /** 586 * Returns the Mime Type of the file, depending on the extension of the filename 587 */ 588 static String getMimeType(String fName) { 589 fName = fName.toLowerCase(); 590 if (fName.endsWith(".jpg") || fName.endsWith(".jpeg") || fName.endsWith(".jpe")) return "image/jpeg"; 591 else if (fName.endsWith(".gif")) return "image/gif"; 592 else if (fName.endsWith(".pdf")) return "application/pdf"; 593 else if (fName.endsWith(".htm") || fName.endsWith(".html") || fName.endsWith(".shtml")) return "text/html"; 594 else if (fName.endsWith(".avi")) return "video/x-msvideo"; 595 else if (fName.endsWith(".mov") || fName.endsWith(".qt")) return "video/quicktime"; 596 else if (fName.endsWith(".mpg") || fName.endsWith(".mpeg") || fName.endsWith(".mpe")) return "video/mpeg"; 597 else if (fName.endsWith(".zip")) return "application/zip"; 598 else if (fName.endsWith(".tiff") || fName.endsWith(".tif")) return "image/tiff"; 599 else if (fName.endsWith(".rtf")) return "application/rtf"; 600 else if (fName.endsWith(".mid") || fName.endsWith(".midi")) return "audio/x-midi"; 601 else if (fName.endsWith(".xl") || fName.endsWith(".xls") || fName.endsWith(".xlv") 602 || fName.endsWith(".xla") || fName.endsWith(".xlb") || fName.endsWith(".xlt") 603 || fName.endsWith(".xlm") || fName.endsWith(".xlk")) return "application/excel"; 604 else if (fName.endsWith(".doc") || fName.endsWith(".dot")) return "application/msword"; 605 else if (fName.endsWith(".png")) return "image/png"; 606 else if (fName.endsWith(".xml")) return "text/xml"; 607 else if (fName.endsWith(".svg")) return "image/svg+xml"; 608 else if (fName.endsWith(".mp3")) return "audio/mp3"; 609 else if (fName.endsWith(".ogg")) return "audio/ogg"; 610 else return "text/plain"; 611 } 612 613 /** 614 * Converts some important chars (int) to the corresponding html string 615 */ 616 static String conv2Html(int i) { 617 if (i == '&') return "&"; 618 else if (i == '<') return "<"; 619 else if (i == '>') return ">"; 620 else if (i == '"') return """; 621 else return "" + (char) i; 622 } 623 624 /** 625 * Converts a normal string to a html conform string 626 */ 627 static String conv2Html(String st) { 628 StringBuffer buf = new StringBuffer(); 629 for (int i = 0; i < st.length(); i++) { 630 buf.append(conv2Html(st.charAt(i))); 631 } 632 return buf.toString(); 633 } 634 635 /** 636 * Starts a native process on the server 637 * @param command the command to start the process 638 * @param dir the dir in which the process starts 639 */ 640 static String startProcess(String command, String dir) throws IOException { 641 StringBuffer ret = new StringBuffer(); 642 String[] comm = new String[3]; 643 comm[0] = COMMAND_INTERPRETER[0]; 644 comm[1] = COMMAND_INTERPRETER[1]; 645 comm[2] = command; 646 long start = System.currentTimeMillis(); 647 try { 648 //Start process 649 Process ls_proc = Runtime.getRuntime().exec(comm, null, new File(dir)); 650 //Get input and error streams 651 BufferedInputStream ls_in = new BufferedInputStream(ls_proc.getInputStream()); 652 BufferedInputStream ls_err = new BufferedInputStream(ls_proc.getErrorStream()); 653 boolean end = false; 654 while (!end) { 655 int c = 0; 656 while ((ls_err.available() > 0) && (++c <= 1000)) { 657 ret.append(conv2Html(ls_err.read())); 658 } 659 c = 0; 660 while ((ls_in.available() > 0) && (++c <= 1000)) { 661 ret.append(conv2Html(ls_in.read())); 662 } 663 try { 664 ls_proc.exitValue(); 665 //if the process has not finished, an exception is thrown 666 //else 667 while (ls_err.available() > 0) 668 ret.append(conv2Html(ls_err.read())); 669 while (ls_in.available() > 0) 670 ret.append(conv2Html(ls_in.read())); 671 end = true; 672 } 673 catch (IllegalThreadStateException ex) { 674 //Process is running 675 } 676 //The process is not allowed to run longer than given time. 677 if (System.currentTimeMillis() - start > MAX_PROCESS_RUNNING_TIME) { 678 ls_proc.destroy(); 679 end = true; 680 ret.append("!!!! Process has timed out, destroyed !!!!!"); 681 } 682 try { 683 Thread.sleep(50); 684 } 685 catch (InterruptedException ie) {} 686 } 687 } 688 catch (IOException e) { 689 ret.append("Error: " + e); 690 } 691 return ret.toString(); 692 } 693 694 /** 695 * Converts a dir string to a linked dir string 696 * @param dir the directory string (e.g. /usr/local/httpd) 697 * @param browserLink web-path to Browser.jsp 698 */ 699 static String dir2linkdir(String dir, String browserLink, int sortMode) { 700 File f = new File(dir); 701 StringBuffer buf = new StringBuffer(); 702 while (f.getParentFile() != null) { 703 if (f.canRead()) { 704 String encPath = URLEncoder.encode(f.getAbsolutePath()); 705 buf.insert(0, "" + conv2Html(f.getName()) + File.separator + ""); 707 } 708 else buf.insert(0, conv2Html(f.getName()) + File.separator); 709 f = f.getParentFile(); 710 } 711 if (f.canRead()) { 712 String encPath = URLEncoder.encode(f.getAbsolutePath()); 713 buf.insert(0, "" + conv2Html(f.getAbsolutePath()) + ""); 715 } 716 else buf.insert(0, f.getAbsolutePath()); 717 return buf.toString(); 718 } 719 720 /** 721 * Returns true if the given filename tends towards a packed file 722 */ 723 static boolean isPacked(String name, boolean gz) { 724 return (name.toLowerCase().endsWith(".zip") || name.toLowerCase().endsWith(".jar") 725 || (gz && name.toLowerCase().endsWith(".gz")) || name.toLowerCase() 726 .endsWith(".war")); 727 } 728 729 /** 730 * If RESTRICT_BROWSING = true this method checks, whether the path is allowed or not 731 */ 732 static boolean isAllowed(File path, boolean write) throws IOException{ 733 if (READ_ONLY && write) return false; 734 if (RESTRICT_BROWSING) { 735 StringTokenizer stk = new StringTokenizer(RESTRICT_PATH, ";"); 736 while (stk.hasMoreTokens()){ 737 if (path!=null && path.getCanonicalPath().startsWith(stk.nextToken())) 738 return RESTRICT_WHITELIST; 739 } 740 return !RESTRICT_WHITELIST; 741 } 742 else return true; 743 } 744 745 //--------------------------------------------------------------------------------------------------------------- 746 747 %> 748 <% 749 request.setCharacterEncoding("utf-8"); 750 response.setContentType("text/html;charset=UTF-8"); 751 //Get the current browsing directory 752 request.setAttribute("dir", request.getParameter("dir")); 753 // The browser_name variable is used to keep track of the URI 754 // of the jsp file itself. It is used in all link-backs. 755 final String browser_name = request.getRequestURI(); 756 final String FOL_IMG = ""; 757 boolean nohtml = false; 758 boolean dir_view = true; 759 //Get Javascript 760 if (request.getParameter("Javascript") != null) { 761 dir_view = false; 762 nohtml = true; 763 //Tell the browser that it should cache the javascript 764 response.setHeader("Cache-Control", "public"); 765 Date now = new Date(); 766 SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US); 767 response.setHeader("Expires", sdf.format(new Date(now.getTime() + 1000 * 60 * 60 * 24*2))); 768 response.setHeader("Content-Type", "text/javascript"); 769 %> 770 <%// This section contains the Javascript used for interface elements %> 771 var check = false; 772 <%// Disables the checkbox feature %> 773 function dis(){check = true;} 774 775 var DOM = 0, MS = 0, OP = 0, b = 0; 776 <%// Determine the browser type %> 777 function CheckBrowser(){ 778 if (b == 0){ 779 if (window.opera) OP = 1; 780 // Moz or Netscape 781 if(document.getElementById) DOM = 1; 782 // Micro$oft 783 if(document.all && !OP) MS = 1; 784 b = 1; 785 } 786 } 787 <%// Allows the whole row to be selected %> 788 function selrow (element, i){ 789 var erst; 790 CheckBrowser(); 791 if ((OP==1)||(MS==1)) erst = element.firstChild.firstChild; 792 else if (DOM==1) erst = element.firstChild.nextSibling.firstChild; 793 <%// MouseIn %> 794 if (i==0){ 795 if (erst.checked == true) element.className='mousechecked'; 796 else element.className='mousein'; 797 } 798 <%// MouseOut %> 799 else if (i==1){ 800 if (erst.checked == true) element.className='checked'; 801 else element.className='mouseout'; 802 } 803 <% // MouseClick %> 804 else if ((i==2)&&(!check)){ 805 if (erst.checked==true) element.className='mousein'; 806 else element.className='mousechecked'; 807 erst.click(); 808 } 809 else check=false; 810 } 811 <%// Filter files and dirs in FileList%> 812 function filter (begriff){ 813 var suche = begriff.value.toLowerCase(); 814 var table = document.getElementById("filetable"); 815 var ele; 816 for (var r = 1; r < table.rows.length; r++){ 817 ele = table.rows[r].cells[1].innerHTML.replace(/<[^>]+>/g,""); 818 if (ele.toLowerCase().indexOf(suche)>=0 ) 819 table.rows[r].style.display = ''; 820 else table.rows[r].style.display = 'none'; 821 } 822 } 823 <%//(De)select all checkboxes%> 824 function AllFiles(){ 825 for(var x=0;x < document.FileList.elements.length;x++){ 826 var y = document.FileList.elements[x]; 827 var ytr = y.parentNode.parentNode; 828 var check = document.FileList.selall.checked; 829 if(y.name == 'selfile' && ytr.style.display != 'none'){ 830 if (y.disabled != true){ 831 y.checked = check; 832 if (y.checked == true) ytr.className = 'checked'; 833 else ytr.className = 'mouseout'; 834 } 835 } 836 } 837 } 838 839 function shortKeyHandler(_event){ 840 if (!_event) _event = window.event; 841 if (_event.which) { 842 keycode = _event.which; 843 } else if (_event.keyCode) { 844 keycode = _event.keyCode; 845 } 846 var t = document.getElementById("text_Dir"); 847 //z 848 if (keycode == 122){ 849 document.getElementById("but_Zip").click(); 850 } 851 //r, F2 852 else if (keycode == 113 || keycode == 114){ 853 var path = prompt("Please enter new filename", ""); 854 if (path == null) return; 855 t.value = path; 856 document.getElementById("but_Ren").click(); 857 } 858 //c 859 else if (keycode == 99){ 860 var path = prompt("Please enter filename", ""); 861 if (path == null) return; 862 t.value = path; 863 document.getElementById("but_NFi").click(); 864 } 865 //d 866 else if (keycode == 100){ 867 var path = prompt("Please enter directory name", ""); 868 if (path == null) return; 869 t.value = path; 870 document.getElementById("but_NDi").click(); 871 } 872 //m 873 else if (keycode == 109){ 874 var path = prompt("Please enter move destination", ""); 875 if (path == null) return; 876 t.value = path; 877 document.getElementById("but_Mov").click(); 878 } 879 //y 880 else if (keycode == 121){ 881 var path = prompt("Please enter copy destination", ""); 882 if (path == null) return; 883 t.value = path; 884 document.getElementById("but_Cop").click(); 885 } 886 //l 887 else if (keycode == 108){ 888 document.getElementById("but_Lau").click(); 889 } 890 //Del 891 else if (keycode == 46){ 892 document.getElementById("but_Del").click(); 893 } 894 } 895 896 function popUp(URL){ 897 fname = document.getElementsByName("myFile")[0].value; 898 if (fname != "") 899 window.open(URL+"?first&uplMonitor="+encodeURIComponent(fname),"","width=400,height=150,resizable=yes,depend=yes") 900 } 901 902 document.onkeypress = shortKeyHandler; 903 <% } 904 // View file 905 else if (request.getParameter("file") != null) { 906 File f = new File(request.getParameter("file")); 907 if (!isAllowed(f, false)) { 908 request.setAttribute("dir", f.getParent()); 909 request.setAttribute("error", "You are not allowed to access "+f.getAbsolutePath()); 910 } 911 else if (f.exists() && f.canRead()) { 912 if (isPacked(f.getName(), false)) { 913 //If zipFile, do nothing here 914 } 915 else{ 916 String mimeType = getMimeType(f.getName()); 917 response.setContentType(mimeType); 918 if (mimeType.equals("text/plain")) response.setHeader( 919 "Content-Disposition", "inline;filename=\"temp.txt\""); 920 else response.setHeader("Content-Disposition", "inline;filename=\"" 921 + f.getName() + "\""); 922 BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(f)); 923 byte buffer[] = new byte[8 * 1024]; 924 out.clearBuffer(); 925 OutputStream out_s = new Writer2Stream(out); 926 copyStreamsWithoutClose(fileInput, out_s, buffer); 927 fileInput.close(); 928 out_s.flush(); 929 nohtml = true; 930 dir_view = false; 931 } 932 } 933 else { 934 request.setAttribute("dir", f.getParent()); 935 request.setAttribute("error", "File " + f.getAbsolutePath() 936 + " does not exist or is not readable on the server"); 937 } 938 } 939 // Download selected files as zip file 940 else if ((request.getParameter("Submit") != null) 941 && (request.getParameter("Submit").equals(SAVE_AS_ZIP))) { 942 Vector v = expandFileList(request.getParameterValues("selfile"), false); 943 //Check if all files in vector are allowed 944 String notAllowedFile = null; 945 for (int i = 0;i < v.size(); i++){ 946 File f = (File) v.get(i); 947 if (!isAllowed(f, false)){ 948 notAllowedFile = f.getAbsolutePath(); 949 break; 950 } 951 } 952 if (notAllowedFile != null){ 953 request.setAttribute("error", "You are not allowed to access " + notAllowedFile); 954 } 955 else if (v.size() == 0) { 956 request.setAttribute("error", "No files selected"); 957 } 958 else { 959 File dir_file = new File("" + request.getAttribute("dir")); 960 int dir_l = dir_file.getAbsolutePath().length(); 961 response.setContentType("application/zip"); 962 response.setHeader("Content-Disposition", "attachment;filename=\"rename_me.zip\""); 963 out.clearBuffer(); 964 ZipOutputStream zipout = new ZipOutputStream(new Writer2Stream(out)); 965 zipout.setComment("Created by jsp File Browser v. " + VERSION_NR); 966 zipout.setLevel(COMPRESSION_LEVEL); 967 for (int i = 0; i < v.size(); i++) { 968 File f = (File) v.get(i); 969 if (f.canRead()) { 970 zipout.putNextEntry(new ZipEntry(f.getAbsolutePath().substring(dir_l + 1))); 971 BufferedInputStream fr = new BufferedInputStream(new FileInputStream(f)); 972 byte buffer[] = new byte[0xffff]; 973 copyStreamsWithoutClose(fr, zipout, buffer); 974 /* int b; 975 while ((b=fr.read())!=-1) zipout.write(b);*/ 976 fr.close(); 977 zipout.closeEntry(); 978 } 979 } 980 zipout.finish(); 981 out.flush(); 982 nohtml = true; 983 dir_view = false; 984 } 985 } 986 // Download file 987 else if (request.getParameter("downfile") != null) { 988 String filePath = request.getParameter("downfile"); 989 File f = new File(filePath); 990 if (!isAllowed(f, false)){ 991 request.setAttribute("dir", f.getParent()); 992 request.setAttribute("error", "You are not allowed to access " + f.getAbsoluteFile()); 993 } 994 else if (f.exists() && f.canRead()) { 995 response.setContentType("application/octet-stream"); 996 response.setHeader("Content-Disposition", "attachment;filename=\"" + f.getName() 997 + "\""); 998 response.setContentLength((int) f.length()); 999 BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(f));1000 byte buffer[] = new byte[8 * 1024];1001 out.clearBuffer();1002 OutputStream out_s = new Writer2Stream(out);1003 copyStreamsWithoutClose(fileInput, out_s, buffer);1004 fileInput.close();1005 out_s.flush();1006 nohtml = true;1007 dir_view = false;1008 }1009 else {1010 request.setAttribute("dir", f.getParent());1011 request.setAttribute("error", "File " + f.getAbsolutePath()1012 + " does not exist or is not readable on the server");1013 }1014 }1015 if (nohtml) return;1016 //else1017 // If no parameter is submitted, it will take the path from jsp file browser1018 if (request.getAttribute("dir") == null) {1019 String path = null;1020 if (application.getRealPath(request.getRequestURI()) != null) {1021 File f = new File(application.getRealPath(request.getRequestURI())).getParentFile();1022 //This is a hack needed for tomcat1023 while (f != null && !f.exists())1024 f = f.getParentFile();1025 if (f != null)1026 path = f.getAbsolutePath();1027 }1028 if (path == null) { // handle the case where we are not in a directory (ex: war file)1029 path = new File(".").getAbsolutePath();1030 }1031 //Check path1032 if (!isAllowed(new File(path), false)){1033 //TODO Blacklist1034 if (RESTRICT_PATH.indexOf(";")<0) path = RESTRICT_PATH;1035 else path = RESTRICT_PATH.substring(0, RESTRICT_PATH.indexOf(";"));1036 }1037 request.setAttribute("dir", path);1038 }%>1039 1041 1042 1043 1044 1045 1046 1047 <%1048 //If a cssfile exists, it will take it1049 String cssPath = null;1050 if (application.getRealPath(request.getRequestURI()) != null) cssPath = new File(1051 application.getRealPath(request.getRequestURI())).getParent()1052 + File.separator + CSS_NAME;1053 if (cssPath == null) cssPath = application.getResource(CSS_NAME).toString();1054 if (new File(cssPath).exists()) {1055 %>1056 1057 <%}1058 else if (request.getParameter("uplMonitor") == null) {%>1059 1079 <%}1080 1081 //Check path1082 if (!isAllowed(new File((String)request.getAttribute("dir")), false)){1083 request.setAttribute("error", "You are not allowed to access " + request.getAttribute("dir"));1084 }1085 //Upload monitor1086 else if (request.getParameter("uplMonitor") != null) {%>1087 <%1090 String fname = request.getParameter("uplMonitor");1091 //First opening1092 boolean first = false;1093 if (request.getParameter("first") != null) first = true;1094 UplInfo info = new UplInfo();1095 if (!first) {1096 info = UploadMonitor.getInfo(fname);1097 if (info == null) {1098 //Windows1099 int posi = fname.lastIndexOf("\\");1100 if (posi != -1) info = UploadMonitor.getInfo(fname.substring(posi + 1));1101 }1102 if (info == null) {1103 //Unix1104 int posi = fname.lastIndexOf("/");1105 if (posi != -1) info = UploadMonitor.getInfo(fname.substring(posi + 1));1106 }1107 }1108 dir_view = false;1109 request.setAttribute("dir", null);1110 if (info.aborted) {1111 UploadMonitor.remove(fname);1112 %>1113 1114 1115 Upload of <%=fname%>1116 Upload aborted.1117 <%1118 }1119 else if (info.totalSize != info.currSize || info.currSize == 0) {1120 %>1121 1122 1123 1124 Upload of <%=fname%>11251126 1129 <%=convertFileSize(info.currSize)%> from <%=convertFileSize(info.totalSize)%>1130 (<%=info.getPercent()%> %) uploaded (Speed: <%=info.getUprate()%>).1131 Time: <%=info.getTimeElapsed()%> from <%=info.getTimeEstimated()%>1132 1133 <%1134 }1135 else {1136 UploadMonitor.remove(fname);1137 %>1138 1139 1140 Upload of <%=fname%>1141 Upload finished.1142 1143 <%1144 }1145 }1146 //Comandwindow1147 else if (request.getParameter("command") != null) {1148 if (!NATIVE_COMMANDS){1149 request.setAttribute("error", "Execution of native commands is not allowed!");1150 }1151 else if (!"Cancel".equalsIgnoreCase(request.getParameter("Submit"))) {1152 %>1153
1127 1128 Launch commands in <%=request.getAttribute("dir")%> 1154 11551156 1184 1185 1186 <%1187 dir_view = false;1188 request.setAttribute("dir", null);1189 }1190 }1191 1192 //Click on a filename, special viewer (zip+jar file)1193 else if (request.getParameter("file") != null) {1194 File f = new File(request.getParameter("file"));1195 if (!isAllowed(f, false)){1196 request.setAttribute("error", "You are not allowed to access " + f.getAbsolutePath());1197 }1198 else if (isPacked(f.getName(), false)) {1199 //ZipFile1200 try {1201 ZipFile zf = new ZipFile(f);1202 Enumeration entries = zf.entries();1203 %>1204<%=LAUNCH_COMMAND %>
1157 <%1158 out.println(" 1178 1179
11801181 jsp File Browser version <%= VERSION_NR%> by www.vonloesch.de1182 1183<%= f.getAbsolutePath()%> 1205 1206 1207Content of <%=conv2Html(f.getName())%>
1208
Name | Uncompressed size | Compressed size | Compr. ratio | Date | 1210 <%1211 long size = 0;1212 int fileCount = 0;1213 while (entries.hasMoreElements()) {1214 ZipEntry entry = (ZipEntry) entries.nextElement();1215 if (!entry.isDirectory()) {1216 fileCount++;1217 size += entry.getSize();1218 long ratio = 0;1219 if (entry.getSize() != 0) ratio = (entry.getCompressedSize() * 100)1220 / entry.getSize();1221 out.println("
---|---|---|---|---|
" + conv2Html(entry.getName())1222 + " | " + convertFileSize(entry.getSize()) + " | "1223 + convertFileSize(entry.getCompressedSize()) + " | "1224 + ratio + "%" + " | "1225 + dateFormat.format(new Date(entry.getTime())) + " |
1236 <%=convertFileSize(size)%> in <%=fileCount%> files in <%=f.getName()%>. Compression ratio: <%=(f.length() * 100) / size%>%1237
1238 1239 <%1240 }1241 catch (ZipException ex) {1242 request.setAttribute("error", "Cannot read " + f.getName()1243 + ", no valid zip file");1244 }1245 catch (IOException ex) {1246 request.setAttribute("error", "Reading of " + f.getName() + " aborted. Error: "1247 + ex);1248 }1249 }1250 }1251 // Upload1252 else if ((request.getContentType() != null)1253 && (request.getContentType().toLowerCase().startsWith("multipart"))) {1254 if (!ALLOW_UPLOAD){1255 request.setAttribute("error", "Upload is forbidden!");1256 }1257 response.setContentType("text/html");1258 HttpMultiPartParser parser = new HttpMultiPartParser();1259 boolean error = false;1260 try {1261 int bstart = request.getContentType().lastIndexOf("oundary=");1262 String bound = request.getContentType().substring(bstart + 8);1263 int clength = request.getContentLength();1264 Hashtable ht = parser1265 .processData(request.getInputStream(), bound, tempdir, clength);1266 if (!isAllowed(new File((String)ht.get("dir")), false)){1267 //This is a hack, cos we are writing to this directory1268 request.setAttribute("error", "You are not allowed to access " + ht.get("dir"));1269 error = true;1270 }1271 else if (ht.get("myFile") != null) {1272 FileInfo fi = (FileInfo) ht.get("myFile");1273 File f = fi.file;1274 UplInfo info = UploadMonitor.getInfo(fi.clientFileName);1275 if (info != null && info.aborted) {1276 f.delete();1277 request.setAttribute("error", "Upload aborted");1278 }1279 else {1280 // Move file from temp to the right dir1281 String path = (String) ht.get("dir");1282 if (!path.endsWith(File.separator)) path = path + File.separator;1283 if (!f.renameTo(new File(path + f.getName()))) {1284 request.setAttribute("error", "Cannot upload file.");1285 error = true;1286 f.delete();1287 }1288 }1289 }1290 else {1291 request.setAttribute("error", "No file selected for upload");1292 error = true;1293 }1294 request.setAttribute("dir", (String) ht.get("dir"));1295 }1296 catch (Exception e) {1297 request.setAttribute("error", "Error " + e + ". Upload aborted");1298 error = true;1299 }1300 if (!error) request.setAttribute("message", "File upload correctly finished.");1301 }1302 // The form to edit a text file1303 else if (request.getParameter("editfile") != null) {1304 File ef = new File(request.getParameter("editfile"));1305 if (!isAllowed(ef, true)){1306 request.setAttribute("error", "You are not allowed to access " + ef.getAbsolutePath());1307 }1308 else{1309 %>1310Edit <%=conv2Html(request.getParameter("editfile"))%>
1315 <%1316 BufferedReader reader = new BufferedReader(new FileReader(ef));1317 String disable = "";1318 if (!ef.canWrite()) disable = " readonly";1319 out.println("1363
");1716 out.println(request.getAttribute("error"));1717 out.println(" |
Name | "1738 + "Size | "1740 + "Type | "1742 + "Date | "1744 + "");1745 if (!READ_ONLY) out.print (" | ");1746 out.println(" | |||
---|---|---|---|---|---|---|---|---|
");1759 String name = URLEncoder.encode(entry[i].getAbsolutePath());1760 String buf = entry[i].getAbsolutePath();1761 out.println(" [" + buf + "]");1763 out.print(" | ||||||||
");1771 out.println(" " + FOL_IMG + "[..]");1773 out.print(" | ||||||||
");1853 }1854 else {1855 out.println(" | ");1856 }1857 out.print(" | " + link + " | ");1858 if (entry[i].isDirectory()) out.print("");1859 else {1860 out.print(" | "1861 + convertFileSize(entry[i].length()) + " | ");1862 }1863 out.println("" + type + " | " + // The file type (extension)1864 date + " | " + // The date the file was created1865 dlink + " | "); // The download link1866 if (!READ_ONLY)1867 out.print ("" + elink + " | "); // The edit link (or view, depending)1868 out.println("
1874 1875 <%=convertFileSize(totalSize)%> in <%=fileCount%> files in <%= dir2linkdir((String) request.getAttribute("dir"), browser_name, sortMode)%>1876 1877
1878 ">1879 1880 1881 <% if (!READ_ONLY) {%>1882 1884 <% } %>1885 <% if (!READ_ONLY) {%>1886 1887 1888 1889 1890 1891 1892 1893 <% } %>1894 1897 <% if (ALLOW_UPLOAD) { %>1898 1899 ">1900 1901 1902 1904 1905 <%} %>1906 <% if (NATIVE_COMMANDS) {%>1907 1908 ">1909 1910 1911 1912 <%1913 }%>1914
1915 <%}%>1916 1917